# -*- coding: UTF-8 -*-
'''
@Project ：push_rk
@File ：codededed.py
@IDE ：PyCharm
@Author ：苦瓜
@Date ：2025/9/28 10:29
@Note: Something beautiful is about to happen !
'''
import numpy as np
import torch
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# 1.	加载乳腺癌数据集
x, y = load_breast_cancer(return_X_y=True)

# 2.	转换为二分类问题（例如，恶性和良性）
print(len(np.unique(y)))
""" 数据已经是二分类问题 """

# 3.	数据标准化
x = StandardScaler().fit_transform(x)

# 4.	转换为PyTorch张量
X = torch.tensor(x, dtype=torch.float)
Y = torch.tensor(y, dtype=torch.float).reshape(-1, 1)

# Y = torch.reshape(Y, (-1, 1))

# 5.	划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, Y, shuffle=True)

# 6.	定义模型
class ClassifierCancer(torch.nn.Module):
    def __init__(self):
        super().__init__()
        self.logistic = torch.nn.Sequential(
            # 7.	修改输入特征数量以匹配数据集
            torch.nn.Linear(in_features=X_train.shape[1], out_features=10),
            torch.nn.Linear(in_features=10, out_features=1),
            # 8.	使用Sigmoid激活函数进行二分类
            torch.nn.Sigmoid()
        )

    def forward(self, x):
        return self.logistic(x)

model = ClassifierCancer()

# 9.	损失函数和优化器
cost = torch.nn.BCELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)

# 10.	训练模型
model.train()
for epoch in range(2000):
    optimizer.zero_grad()
    y_pred_train = model(X_train)
    loss_ = cost(y_pred_train, y_train)
    loss_.backward()
    optimizer.step()
    if epoch % 10 == 0:
        print(f"<Train {epoch} loss is :-> ({loss_})>")

# 11.	测试模型
model.eval()
# 12.	将概率转换为类别（0或1）
y_pred_test = model(X_test).argmax(axis=1)
# 13.	计算准确率
print(f"<Test acc is :-> ({(y_pred_test==y_test).float().mean()})>")
